import React, { Component } from 'react'
import { Select, Input, Button, Card, Icon, Table, message } from 'antd'
import LinkButton from '../../components/link-button/link-button'
import { reqProductList, reqSearchList, reqUpdateGoodStatus } from '../../api/index'
import { PAGE_SIZE } from '../../utils/constants'
import memoryUtils from '../../utils/memoryUtils'
import throttle from 'lodash.throttle'

const { Option } = Select;

export default class ProductHome extends Component {

  state = {
    // 商品列表
    productList: [],
    isLoading: false,
    // 商品的总数量
    total: 0,
    // 默认的select被选中的值
    searchType: '请选择',
    // 默认input搜索框的关键字
    searchName: '',
  }

  // 获取select的值
  getSelectValue = (value) => {
    // 改变选中的状态
    this.setState({ searchType: value })
    console.log(`selected ${value}`);
  }


  // 获取input输入的关键字
  getInputValue = (e) => {
    // 获取输入框的值
    let searchName = e.target.value
    // 改变输入的值
    this.setState({ searchName })
  }


  updateGoodStatus = throttle(async (productId, status) => {
    // 点击就需要改变状态
    status = status === 1 ? 2 : 1

    // 发送请求
    const result = await reqUpdateGoodStatus(productId, status)

    // 判断是否更新成功
    if (result.status === 0) {
      // 重新渲染商品列表界面
      this.getProductList(this.pageNum)
      // 提示更新成功
      message.success('更新状态成功')
    }
  },2000)

  /* 
   异步获取指定页码商品分页(可能带搜索)列表显示
 */
  getProductList = async (pageNum) => {
    //  保存当前的搜索页面
    this.pageNum = pageNum

    const { searchName, searchType } = this.state
    // 发送请求之前
    this.setState({ isLoading: true })

    let result
    //  分页搜索
    if (!this.isSearch) {
      // 发送请求获取数据
      result = await reqProductList(pageNum, PAGE_SIZE)
    } else {
      result = await reqSearchList({ pageNum, pageSize: PAGE_SIZE, searchName, searchType })
    }

    // 判断是否能成功接收
    if (result.status === 0) {
      const { list, total } = result.data

      // 更新状态
      this.setState({
        productList: list,
        total,
        isLoading: false
      })
    }
  }

  // 初始化table列表
  initTable = () => {
    this.columns = [
      {
        title: '商品名称',
        dataIndex: 'name'
      },
      {
        title: '商品描述',
        dataIndex: 'desc',
      },
      {
        title: '价格',
        width: 100,
        dataIndex: 'price',
        render: (price) => '￥' + price
      },
      {
        title: '状态',
        width: 100,
        // render: ({_id,status}) => {
        //   let btnText = '下架'
        //   let text = '在售'
        //   if (status === 2) {
        //     btnText = '上架'
        //     text = '已下架'
        //   }
        //   return(
        //     <span>
        //       <Button type="primary" onClick={() => this.updateGoodStatus(_id,status)}>{btnText}</Button>
        //       <span>{text}</span>
        //     </span>
        //   )
        // },
        render: ({ _id, status }) => (
          <span>
            <Button type="primary" onClick={() => this.updateGoodStatus(_id, status)}>{status === 1 ? '上架' : '下架'}</Button>
            <span>{status === 1 ? '已下架' : '在售'}</span>
          </span>
        )
      },
      {
        title: '操作',
        render: (product) => (
          <span>
            <LinkButton onClick={() => {
              // 跳转之前将数据存储到memoryUtils中
              memoryUtils.product = product
              this.props.history.push('/admin/product/detail')
            }
            }>详情</LinkButton>
            <LinkButton onClick={() => {
              // 跳转之前将数据存储到memoryUtils中
              memoryUtils.product = product
              this.props.history.push('/admin/product/addupdate')
              }
            }>修改</LinkButton>
          </span>
        )
      },
    ];
  }


  UNSAFE_componentWillMount() {
    this.initTable()
  }

  componentDidMount() {
    this.getProductList(1)
  }

  render() {
    // 表头左侧
    const title = (
      <header>
        <Select
          value={this.state.searchType}
          style={{ width: 120 }}
          onChange={(value) => { this.getSelectValue(value) }}
        >
          <Option value="productName">按名称搜索</Option>
          <Option value="productDesc">按描述搜索</Option>
        </Select>
        <Input
          placeholder="关键字"
          style={{ width: 200, margin: 10 }}
          value={this.state.searchName}
          onChange={(e) => { this.getInputValue(e) }}
        />
        <Button type="primary" onClick={() => { 
          this.isSearch = true
          this.getProductList(1)
         }}>搜 索</Button>
      </header>
    )

    // 表头右侧
    const extra = (
      <Button type="primary" onClick={() => {
        // 跳转之前将内存中的product清空
        memoryUtils.product = ''
        return this.props.history.push('/admin/product/addupdate')
      }
      }
      >
        <Icon type="plus" />
                添加商品
      </Button>
    )
    return (
      <div>
        <Card title={title} extra={extra}>
          <Table
            columns={this.columns}
            dataSource={this.state.productList}
            rowKey="_id"
            bordered
            loading={this.state.isLoading}
            pagination={{ total: this.state.total, defaultPageSize: PAGE_SIZE, showQuickJumper: true, onChange: this.getProductList, current: this.pageNum }}
          />,
                  </Card>

      </div>
    )
  }
}


/**
 * 搜索分页列表
 *
 * 1. 看接口文档：需要传给后台的是这些参数
 * pageNum, pageSize, productName, productDesc
 *
 * 2. 但是productName和productDesc是需要根据select选择框来选择的，因此定义这个接口的时候需要传递变量接收select的值
 * export const reqSearchList = ({pageNum, pageSize, searchName, searchType}) => {
    return ajax({
        method:'get',
        url:'/manage/product/search',
        params:{
            pageNum,
            pageSize,
            // 加上[], 是从普通的字符串变为变量，属性名不确定
            [searchType]: searchName
        }
    })
}
 *
 * 3. 收集select和input中的value，可使用受控组件或则非受控组件
 *
 * 4. 定义默认渲染的select值和input到 state 中
 * state={
      // 默认的select被选中的值
      searchType:'all',
      // 默认input搜索框的关键字
      searchName: ''
    }
 *
 * 5. 修改组件的值是根据变量的改变而改变 this.state.searchType 和 this.state.searchName
 *  <Select value={this.state.searchType} style={{ width: 120 }} >
    <Option value="all">全部</Option>
    <Option value="productName">按名称搜索</Option>
    <Option value="productDesc">按描述搜索</Option>
    </Select>
    <Input placeholder="关键字" style={{width:200,margin:10}} value={this.state.searchName} />
    <Button type="primary">搜 索</Button>
 *
 *
 * 6. 监听select选中的值
 * <Select
    value={this.state.searchType}
    style={{ width: 120 }}
    onChange={(value) => {this.handleChange(value)}}
    >
 *
 * 7. 监听input输入的值
 * <Input
    placeholder="关键字"
    style={{width:200,margin:10}}
    value={this.state.searchName}
    onChange={(e) => {this.getInputValue(e)}}
    />
 *
 * 8. 搜索分页请求或普通分页请求（直接在原来的getProductList进行修改即可）
 * 判断什么时候使用一般分页，什么时候使用搜索分页
 *
 *  let result
    //  分页搜索
    if(searchType==='all' || !searchName){
      // 发送请求获取数据
      result = await reqProductList(pageNum, PAGE_SIZE)
    }else{
      result = await reqSearchList({pageNum,pageSize:PAGE_SIZE,searchName, searchType})
    }
 *
 *
 */



/**
 * 商品上架和下架处理
 * 1. 写商品的接口请求函数
 * 2. 给点击按钮绑定监听事件
 * 3. 由于原来的设置了dataIndex: 'status',但这个只能获取到status，不能获取商品的id，因此需要去除dataIndex并且改造render，render中的内容直接读取的是data中的属性值
 *
 * render: ({status, _id}) => (
     <span>
       <Button type="primary" onChange={() => this.updataGoodStatus(status, _id)}>{status===1?'上架':'下架'}</Button>
     <span>{status===1?'已下架':'在售'}</span>
     </span>
   )
 *
 * 4. 写更新状态的函数
 * updataGoodStatus=(status,productId)=>{
   // 计算更新后的值
   status = status === 1 ? 2 : 1
   // 请求更新
   const result = await reqUpdateStatus(productId, status)
   if (result.status === 0) {
     message.success('更新商品状态成功!')
     this.getProducts(1)
   }
 *
 * 5. 出现的bug：在其他页更新完商品状态都会跳转到第一页，需要处理为更新完商品状态停留在当前页
 *
 *        5.1 将当前页的作为变量存起来
 * getProductList=async (pageNum)=>{
    // 保存当前请求的页码
   this.pageNum = pageNum
 * }
 *
 *
 *        5.2 修改更新后为当前页
 * updataGoodStatus=(status,productId)=>{
   status = status === 1 ? 2 : 1
   const result = await reqUpdateStatus(productId, status)
   if (result.status === 0) {
     message.success('更新商品状态成功!')
     this.getProducts(this.pageNum)
   }
 *
 *
 * 6. 出现的bug：第二页点击上架/下架后进行搜索，显示的内容为第一页的数据，但是页码没有跳转到第一页
 *
 * 需修改分页器（新增到对应的内容中）
 * <Table
     pagination={{
       current: this.pageNum
     }}
   />
 *
 *
 *
 * 存在的bug，点击修改后再点击添加按钮，页面变为修改页面
 * 解决办法：在添加按钮跳转之前清空 memoryUtils 的 product
 * <Button type="primary" onClick={() => {
     memoryUtils.product = {}
     this.props.history.push('/product/addupdate')
   }}>
     <Icon type="plus" />
     添加商品
   </Button>
 *
 *
 * 
 * 
 * 存在的bug：
 * 疯狂点击上架/下架按钮，会频繁出现message更新成功的提示
 * 安装库 lodash
 * 
 * $ {sudo -H} npm i -g npm 或
 * $ npm i --save lodash
 * 
 * 引入对应的模块
 * import throttle from 'lodash.throttle' 包装回调函数，生成节流的函数
 * 
 * 使用
 * 用throttle包裹需要节流的函数
 * updateGoodStatus = throttle(async (productId, status) => {
    // 点击就需要改变状态
    status = status === 1 ? 2 : 1

    // 发送请求
    const result = await reqUpdateGoodStatus(productId, status)

    // 判断是否更新成功
    if (result.status === 0) {
      // 重新渲染商品列表界面
      this.getProductList(this.pageNum)
      // 提示更新成功
      message.success('更新状态成功')
    }
  },2000)
 * 
 */